<?php

/**
 * 下单服务
 */
namespace App\Service\OrderService\OrderInterfaceService;

use App\Model\PssModel\FreightTemplateArea;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Service\Volidate\OrderCreateVolidate;
use App\Model\PssModel\Order;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\OrderSupplier;
use App\Model\PssModel\OrderGoods;
use App\Model\PssModel\OrderSupplierGoods;
use App\Model\PssModel\TemplateArea;
use App\Model\PssModel\ShopSeckillUserGoods;
use Hyperf\DbConnection\Db;
use App\Model\PssModel\TemplateDeliveryArea;
use App\Service\CommodityService\CommodityStockService;
use App\Model\CommodityModel\CommodityArchives;
use App\Model\CommodityModel\CommodityOptimizationBbc;
use App\Service\OrderService\OrderSupplierEventLogMessageService as OSELMS;
use App\Model\PssModel\OrderSupplierAmountExtra;

class CreateOrder extends BaseService
{
    /**
     * 云仓系统下单主入口中心
     * @param array $param
     * @return mixed
     */
    public function index( $param = [] )
    {
        try {
            $res = OrderCreateVolidate::checkParametersByRequest($param);
            if( $res['code'] != Normal::SUC ) {
                return $res;
            }
            
            $orderParameter     = $res['data'];
            $requestData        = $orderParameter['requestData'];
            $binfo              = $orderParameter['binfo'];
            $bid                = $binfo['bid'];
            $orderSn            = $requestData['orderSn'];
            $orderTradeType     = !empty($requestData['orderTradeType']) ? $requestData['orderTradeType'] : 1;
            if( in_array($orderTradeType,[OrderSupplier::order_trade_type_coupon]) ) 
            {
                return OrderCoupon::instance()->placeOrder($orderParameter);
            }
            
            //验证订单号已经创建
            $order = Order::instance()->info(['bid' => $bid,'order_sn' => $orderSn],['id']);
            if( !empty($order) ) {
                return Normal::returnCode('100000',"当前订单号【{$orderSn}】不能重复提交-2");
            }
            
            //正常下单
            //==================================BBC渠道或者第三方渠道下单逻辑===========================================//
            if( !isset($requestData['order_type']) || in_array($requestData['order_type'],OrderPay::YW_ORDER_TYPE_ARR))
            {
                //请求微服务接口获取商品数据
                $res = $this->getOrderGoodsListsByMicService($orderParameter);
                if( $res['code'] != Normal::SUC ) {
                    return $res;
                }
            
                //组装分组数据
                $micServiceGoods = $res['data']['micServiceGoods'];
                //运费模板
                $templateList    = $res['data']['templateList'];
                //禁售区域
                $noSaleArea      = $res['data']['noSaleArea'];

                //是否跳过高德省市区判断校验
                if( $binfo['is_router_user'] != 1 ) {
                    //获取高德省市区信息
                    $addressRes = TemplateDeliveryArea::instance()->getDeliveryAddressInfoByAddress($requestData);
                    if( $addressRes['code'] != Normal::SUC ) {
                        return $addressRes;
                    }
                    $regions = $addressRes['data'];
            
                    //计算获取每个模板对应区域运费
                    $res = TemplateArea::instance()->getUserRegionIdsByAddress($templateList,$regions,$noSaleArea);
                    if( $res['code'] != Normal::SUC ) {
                        return $res;
                    }
                    $requestData['templateList'] = $res['data']['template_list'];
                } else {
                    $requestData['templateList'] = [];
                }
            } else {
            
                //==================================云仓商城下单逻辑===========================================//
                //获取商城接口过来的数据
                $userGoodsList      = $orderParameter['requestData']['goods'];
                $goodsList          = $orderParameter['requestData']['realGoodsList'];
                $authGoods          = $orderParameter['requestData']['authGoodsList'];
                $orderGoodsMap = [];
                foreach ($userGoodsList as $item ) {
                    $orderGoodsMap[$item['goodsSku']][] = $item;
                    unset($item);
                }
                //下单商品数据分组
                $userGoodsList      = array_column($userGoodsList,null,'skuCode');
                //循环组装下单商品分组
                $micServiceGoods = $supplierGoodsList = [];
                foreach ($goodsList as $currentGoods )
                {
                    //自编码
                    $skucode        = $currentGoods['skuCode'];
                    //供应商编码
                    $supplierCode   = $currentGoods['supplierCode'];
                    //组装分组
                    $supplierGoodsList[$supplierCode][$skucode] = $currentGoods;
                    //下单商品
                    $userGoodsList[$supplierCode][$skucode] = $orderGoodsMap[$skucode];
                    //授权商品分组
                    $authGoodsList[$supplierCode][$skucode] = $authGoods[$skucode];
            
                    //处理下单接口参数 判断是接口仓才进行
                    $JsonBody = @json_decode($currentGoods['JsonBody'],true);
                    $JsonBody = $JsonBody ? $JsonBody : [];
            
                    //下单服务组装
                    $micServiceGoods[$supplierCode] = [
                        'supplierCode'              => $supplierCode,
                        'isCombineOrders'           => $currentGoods['isCombineOrders'],
                        'warehouseAccount'          => $currentGoods['warehouseAccount'],
                        'warehouseID'               => $currentGoods['warehouseID'],
                        'supplierID'                => $currentGoods['supplierID'],
                        'orderDockMode'             => $currentGoods['orderDockMode'],
                        'orderDeclare'              => $currentGoods['orderDeclare'],
                        'payDeclare'                => $currentGoods['payDeclare'],
                        'apiBody'                   => $JsonBody,
                        'thirdPartyPlatformCode'    => $currentGoods['thirdPartyPlatformCode'],
                        'goodsList'                 => $supplierGoodsList[$supplierCode],
                        'authGoodsList'             => $authGoodsList[$supplierCode],
                        'userGoodsList'             => $userGoodsList[$supplierCode],
                        'canModifyStock'            => $currentGoods['canModifyStock'],
                        'FastDeliveryType'          => 0,
                    ];
                }
            
                //不支持支付单海关拆单报关接口的支付方式
                if( !$requestData['isSplitOrder'] ) {
                    //检查商品下单情况
                    $res = $this->checkoutOrderCommodityStatus(['micServiceGoodsData'=>$goodsList,'orderParam'=>$orderParameter]);
                    if( $res['code'] != Normal::SUC ) {
                        return $res;
                    }
                }
            }
            
            //组装商户主订单数据
            $resOrder = OrderSupplier::instance()->getUserMainOrderInfo([
                'supplierGoodsInfo'     => $micServiceGoods,
                'binfo'                 => $binfo,
                'order'                 => $requestData,
            ]);
            
            if( $resOrder['code'] != Normal::SUC ) {
                return $resOrder;
            }
            
            $order              = $resOrder['data']['order'];
            $orderGoods         = $resOrder['data']['goods'];
            $stockDeductInfo    = $resOrder['data']['stockDeductInfo'];
            
            //组装供应商子订单数据
            $res = $this->orderSupplierGroupGoodsUpload([
                'order'             => $requestData,
                'binfo'             => $binfo,
                'micServiceGoods'   => $micServiceGoods,
            ]);
            
            if( $res['code'] != Normal::SUC ) {
                return $res;
            }
            
            //合并供应商订单
            $supplierOrderList = $res['data'];
            $insertSupplierOrderAll = $insertSupplierGoodsAll = $orderItems = $seckill_info = $insertSupplierAmountExtra = [];
            foreach ($supplierOrderList as $orderItem ) {
                array_push($insertSupplierOrderAll, $orderItem['order']);
                array_push($insertSupplierAmountExtra, $orderItem['supplierAmountExtra']);
                array_push($orderItems, $orderItem['orderItems']);
                $seckill_info = array_merge($seckill_info, $orderItem['seckill_info']);
                $insertSupplierGoodsAll = array_merge($insertSupplierGoodsAll, $orderItem['goods']);
                unset($orderItem);
            }
        }  catch ( \Throwable $th ) {
            return Normal::returnCode(Normal::FAIL,"当前处理异常[{$th->getMessage()}]",[
                'errorFile' => $th->getFile(),
                'errorLine' => $th->getLine()
            ]);
        }
        
        try {
        
            OrderSupplier::instance()->startTrans();
            
            //处理用户秒杀活动数据
            $resSeckill = $this->addUserSecKillGoods($seckill_info,$binfo);
            if( !$resSeckill ) {
                OrderSupplier::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,"当前业务繁忙，请稍后再试");
            }
            
            $resId = Order::instance()->insert($order);
            if( !$resId) {
                OrderSupplier::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,"创建订单失败-1");
            }
        
            $resId = OrderGoods::instance()->insert($orderGoods);
            if( !$resId) {
                OrderSupplier::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,"创建订单失败-2");
            }
        
            $resId = OrderSupplier::instance()->insert($insertSupplierOrderAll);
            if( !$resId) {
                OrderSupplier::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,"创建订单失败-3");
            }
        
            $resId = OrderSupplierGoods::instance()->insert($insertSupplierGoodsAll);
            if( !$resId) {
                OrderSupplier::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,"创建订单失败-4");
            }
            
            
            //写入资金扩展表数据
            OrderSupplierAmountExtra::instance()->insert($insertSupplierAmountExtra);
            
            //需要扣除库存条件
            if(!empty($stockDeductInfo) && $binfo['is_router_user'] != 1) {
                $res = CommodityStockService::instance()->orderReduceStock($binfo['bid'],$stockDeductInfo,'-');
                if( $res['code'] != Normal::SUC ) {
                    OrderSupplier::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,"库存服务接口失败【{$res['msg']}】");
                }
            }
            
            //提交事务之前，写入订单行为日志,排除大平台订单日志
            if( !isset(OrderCreateVolidate::$sensitive_user[$binfo['user_tag']]) ) 
            {
                foreach ($insertSupplierOrderAll as $SupplierOrderItem) 
                {
                    $result = OSELMS::instance()->publish((string)$SupplierOrderItem['id'], OSELMS::EVENT_TYPE_ORDER_CREATE, "创建订单");
                    if( $result['code'] != Normal::SUC ) 
                    {
                        OrderSupplier::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL,"系统内部异常，请稍后再试【{$result['msg']}】");
                    }
                }
            }
            
            OrderSupplier::instance()->commit();
            return Normal::returnCode(Normal::SUC,"创建订单成功",[
                "orderItems" => $orderItems
            ]);
        } catch ( \Throwable $e ) {
            OrderSupplier::instance()->rollback();
            return Normal::returnCode($e->getCode(),$e->getMessage());
        }
    }
    
    /**
     * 写入或者更新用户秒杀商品数据
     * @param array $seckill_goods_list
     */
    public function addUserSecKillGoods( $seckill_info = [],$binfo ) 
    {
        if( empty($seckill_info) ) {
            return true;
        }
        
        $bid    = $binfo['bid'];
        $time   = time();
        foreach ($seckill_info as $item ) {
            $secinfo    = @json_decode($item['seckill_info'],true);
            $seckill_id = $secinfo['id'];
            $goods_id   = $item['goods_id'];
            $goods_num  = $item['goods_num'];
            $where = [
                'bid'               => $bid,
                'seckill_id'        => $seckill_id,
                'seckill_goods_id'  => $goods_id
            ];
            $data = [
                'version'   => Db::raw("version+1"),
                'buy_count' => Db::raw("buy_count+{$goods_num}"),
                'md'        => $time
            ];
            $isRow = ShopSeckillUserGoods::instance()->info($where);
            if( !empty($isRow) ) {
                return ShopSeckillUserGoods::instance()->edit(['id'=>$isRow['id'],'version'=>$isRow['version']],$data);
            } else {
                return ShopSeckillUserGoods::instance()->insert([
                    'id'                    => IdService::instance()->getGoodsID(),
                    'bid'                   => $bid,
                    'seckill_id'            => $seckill_id,
                    'seckill_goods_id'      => $item['goods_id'],
                    'seckill_skucode'       => $item['skucode'],
                    'seckill_barcode'       => $item['barcode'],
                    'seckill_goods_name'    => $item['goods_name'],
                    'buy_count'             => $goods_num,
                    'cd'                    => $time
                ]);
            }
        }
    }
    
    /**
     * 按照供应商进行订单拆解
     * @param array $param
     */
    public function orderSupplierGroupGoodsUpload( $param = [] )
    {
        $micServiceGoods = $param['micServiceGoods'];
        $binfo = $param['binfo'];
        $order = $param['order'];
        $orderPush = [];
        $orderItems = [];
        foreach ($param['micServiceGoods'] as $item ) 
        {
            $orderDockMode = $item['orderDockMode'];
            $supplierCode  = $item['thirdPartyPlatformCode'] ? $item['thirdPartyPlatformCode'] : $item['supplierCode'];
            //验证仓库类型
            $supplierCode = ucFirst( $orderDockMode == 0 ? $supplierCode : 'normal' );
            $serviceClass  = "App\\Service\\OrderService\\OrderRouteService\\{$supplierCode}";
            if( !class_exists($serviceClass) ) {
                return Normal::returnCode(Normal::FAIL,"抱歉，当前商品的供应商编码【{$supplierCode}】订单业务对接配置错误，请联系管理员核对之后，重新下单！");
            }
            
            $requestMethod = 'createOrder';
            if( !method_exists($serviceClass,$requestMethod) ) {
                return Normal::returnCode(Normal::FAIL,"{$serviceClass} {$requestMethod} methods not existed");
            }
            
            $goodsList = $item['goodsList'];
            $res = $serviceClass::instance()->$requestMethod([
                'supplierGoodsInfo'     => $item,
                'order'                 => $order,
                'binfo'                 => $binfo,
            ]);
            
            if( $res['code'] != Normal::SUC ) {
                return Normal::returnCode(Normal::FAIL,"{$res['msg']},库存不足【{$supplierCode}】");
            }
            
            //分组需要进行订单批量推送接口
            if( isset($res['data']['orderPush']) )  {
                $orderPush = array_merge($orderPush,$res['data']['orderPush']);
            }
            
            //自建仓或者只有支付推送订单接口供应商
            if( isset($res['data']['orderItems']) )  {
                $orderItems = array_merge($orderItems,$res['data']['orderItems']);
            }
        }
        
        if( !empty($orderPush) ) {
            $resOrderPush = $this->startPlaceOrderRequest($orderPush, $order['templateList']);
            if( $resOrderPush['code'] != Normal::SUC ) {
                return $resOrderPush;
            }
            $orderItems = array_merge($orderItems,$resOrderPush['data']);
        }
        
        return Normal::returnCode(Normal::SUC,"OK",$orderItems);
    }
    
    /**
     * 开始进行批量推送是
     * @param array $orderPush
     * @param array $deliveryTemplateInfo 收获地区运费模板
     */
    public function startPlaceOrderRequest( $parameter = [], $deliveryTemplateInfo)
    {
        $parameter = array_map(function ( & $value ) {
            $value['data'] = json_decode($value['data'],true);
            return $value;
        }, $parameter);
        $resTask = TaskWorker::instance()->addTask($parameter);
        $pushOrder = [];
        foreach ($resTask as $task )
        {
            $request = $task['request'];
            //根据供应商进行接口响应参数校验返回
            $supplierCode = ucFirst($request['tag']);
            $serviceClass  = "App\\Service\\OrderService\\OrderRouteService\\{$supplierCode}";
            if( !class_exists($serviceClass) ) {
                return Normal::returnCode(Normal::FAIL,"{$serviceClass} not existed");
            }
            
            $requestMethod = 'getCreateOrderCode';
            if( !method_exists($serviceClass,$requestMethod) ) {
                return Normal::returnCode(Normal::FAIL,"{$serviceClass} {$requestMethod} methods not existed");
            }
            
            $res = $serviceClass::instance()->$requestMethod($task['response']);
            if( $res['code'] != Normal::SUC ) {
                return Normal::returnCode($res['code'],"下单服务【{$supplierCode}】处理失败：【{$res['msg']}】");
            }
            
            //得到供应商订单号
            $param = @json_decode($request['param'],true);
            //如果是上游进行了拆单
            if( isset($res['data']['orderList']) ) 
            {
                $orderList = $res['data']['orderList'];
                $supplierGoodsLists = array_column($param['supplierGoodsInfo']['goodsList'],null,'supplierSKUCode');
                $userGoodsList = $param['supplierGoodsInfo']['userGoodsList'];
                foreach ($orderList as $orderItem )
                {
                    $goods = [];
                    foreach ($orderItem['orderGoods'] as $item ) 
                    {
                        //当前供应商商品
                        $currentSupplierGoods = $supplierGoodsLists[$item['goodsSku']];
                        $skuCode = $currentSupplierGoods['skuCode'];
                        
                        //当前下单商品
                        $currentOrderGoodsMap = array_column($userGoodsList[$skuCode],null,'goodsSpecNum');
                        $goodsSpecNum = $item['goodsSpecNum'];
                        $currentGoods = $currentOrderGoodsMap[$goodsSpecNum];
                        $goods[] = [
                            'goodsBatchNo'  						=> $currentSupplierGoods['batchNo'],
                            'goodsSku'      						=> $skuCode,
                            'goodsNum'      						=> $item['goodsNum'],
                            'goodsPrice'    						=> $currentGoods['goodsPrice'],
                            'goodsTax'      						=> 0.00,
                            'goodsSpecNum'  						=> $goodsSpecNum,
                            'startExpDate'  						=> $currentSupplierGoods['batchNo'],
                            'endExpDate'    						=> $currentSupplierGoods['batchNo'],
                            'freight'       						=> $currentGoods['freight']??'0.00',
                            'discountMoney' 						=> $currentGoods['discountMoney']??'0.00',
                            'discountPointMoney'                    => $currentGoods['discountPointMoney']??'0.00',
                            'discountRedEnvelopeMoney'              => $currentGoods['discountRedEnvelopeMoney']??'0.00',
                            'discountActivityMoney'                 => $currentGoods['discountActivityMoney']??'0.00',
                            'discountCouponMoney'                   => $currentGoods['discountCouponMoney']??'0.00',
                            'discountPaywayMoney'                   => $currentGoods['discountPaywayMoney']??'0.00',
                            'discountPrecardMoney'                  => $currentGoods['discountPrecardMoney']??'0.00',
                            'discountPoints'                        => $currentGoods['discountPoints']??'0.00',
                            'goodsSingleOrderPrecardBalanceMoney'   => $currentGoods['goodsSingleOrderPrecardBalanceMoney']??'0.00',
                            'goodsSingleDiscountActivityMoney'      => $currentGoods['goodsSingleDiscountActivityMoney']??'0.00',
                            'goodsSingleDiscountCouponMoney'        => $currentGoods['goodsSingleDiscountCouponMoney']??'0.00',
                            'goodsSingleDiscountPaywayMoney'        => $currentGoods['goodsSingleDiscountPaywayMoney']??'0.00',
                            'goodsSingleDiscountPointMoney'         => $currentGoods['goodsSingleDiscountMoney']??'0.00',
                            'goodsSingleDiscountRedEnvelopeMoney'   => $currentGoods['goodsSingleDiscountRedEnvelopeMoney']??'0.00',
                            'goodsSingleDiscountMoney'              => $currentGoods['goodsSingleDiscountMoney']??'0.00'
                        ];
                        unset($item);
                    }
                    
                    //订单创建参数
                    $orderCreateParam = $param;
                    if( !isset($orderCreateParam['order']['supplier_dsn']) ) {
                        $orderCreateParam['order']['supplier_dsn'] = IdService::instance()->getOmsID();
                    }
                    $orderCreateParam['order']['supplier_csn']  = $orderItem['supplier_csn'];
                    $orderCreateParam['order']['goods']         = $goods;
                    $orderCreateParam['order']['templateList']  = $deliveryTemplateInfo;
                    $res = OrderSupplier::instance()->getSupplierCreateOrderData($orderCreateParam);
                    if( $res['code'] != Normal::SUC ) {
                        return $res;
                    }
                    $pushOrder[] = $res['data'];
                }
            } else if( isset($res['data']['supplier_csn']) ) {
                
                $param['order']['supplier_csn'] = $res['data']['supplier_csn'];
                $param['order']['templateList'] = $deliveryTemplateInfo;
                $res = OrderSupplier::instance()->getSupplierCreateOrderData($param);
                if( $res['code'] != Normal::SUC ) {
                    return $res;
                }
                $pushOrder[] = $res['data'];
            } else {
                return Normal::returnCode(Normal::FAIL,"响应解析异常");
            }
        }
        
        return Normal::returnCode(Normal::SUC,"OK",$pushOrder);
    }
    
    /**
     * 获取下单商品
     * @param array $orderGoods
     * @param array $authGoods
     */
    public function getOrderResetGoodsList( $orderGoods = [] ,$CommodityArchiveGoods = [] ,$is_router_user = 0 )
    {
        $SkuMap = array_column($CommodityArchiveGoods,null,'SKUCode');
        $dataList = $orderGoodsMap = [];
        foreach ($orderGoods as $item ) 
        {
            $goodsSku = $item['goodsSku'];
            $orderGoodsMap[$goodsSku][] = $item;
            $dataList[] = [
                'skucode'       => $item['goodsSku'],
                'goods_id'      => $is_router_user ? $SkuMap[$goodsSku]['SKUCode'] : $SkuMap[$goodsSku]['SkuID'],//处理路由模式数据
                'batch_no'      => $item['goodsBatchNo'],
                'spec_num'      => $item['goodsSpecNum'],
                'goods_num'     => $item['goodsNum'],
            ];
        }
        return [
            'orderGoodsGroup'   => $orderGoodsMap,
            'orderGoods'    => $dataList
        ];
    }
    
    /**
     * 获取下单订单快照商品数据
     * @param array $param
     */
    public function getOrderGoodsListsByMicService( $param = [] )
    {
        $requestData  = $param['requestData'];
        $orderGoods = $requestData['goods'];
        $binfo      = $param['binfo'];
        $bid        = $binfo['bid']; 
        $SkuCodes   = array_column($orderGoods,'goodsSku');
        
        //查询路由模式
        if( $binfo['is_router_user'] == 1 ) 
        {
            $CommodityArchiveGoods = CommodityOptimizationBbc::instance()->getSkuIDListByBuIDAndSupplierSkuCodes($bid,$SkuCodes);
            if( empty($CommodityArchiveGoods) ) {
                $skuCodeString = implode(",", $SkuCodes);
                return Normal::returnCode(Normal::FAIL,"路由供应商商品已下架[1000]，请核对检查当前渠道商优选商品池列表数据供应商SKU是否 存在！[{$skuCodeString}]");
            }
            
            $uniqueSkuCodes = array_unique($SkuCodes);
            if( count($CommodityArchiveGoods) != count($uniqueSkuCodes) ) {
                $skuCodeString = implode(",", $uniqueSkuCodes);
                return Normal::returnCode(Normal::FAIL,"路由供应商商品存在相同数据，请联系运营相关人员核对处理[{$skuCodeString}]");
            }
            
            $CommodityArchiveSkuCodes = array_column($CommodityArchiveGoods,"SKUCode");
            $diffGoods = array_diff($SkuCodes,$CommodityArchiveSkuCodes);
            if( !empty($diffGoods) ){
                $string = implode(",", $diffGoods);
                return Normal::returnCode(Normal::FAIL,"你所购买的商品【{$string}】暂无库存，请联系客服[1001]");
            }
            $is_router_user = 1;
        } else {
            $CommodityArchiveGoods = CommodityArchives::instance()->getSkuIDListBySkuCodes($SkuCodes);
            if( empty($CommodityArchiveGoods) ) {
                return Normal::returnCode(Normal::FAIL,"你所购买的商品暂无库存，请联系客服[1000]");
            }
            
            $CommodityArchiveSkuCodes = array_column($CommodityArchiveGoods,"SKUCode");
            $diffGoods = array_diff($SkuCodes, $CommodityArchiveSkuCodes);
            if( !empty($diffGoods) ){
                $string = implode(",", $diffGoods);
                return Normal::returnCode(Normal::FAIL,"你所购买的商品【{$string}】暂无库存，请联系客服[1001]");
            }
            $is_router_user = 0;
        }
        
        //获取下单sku分组及扣除扣除情况
        $orderGoodsGroup = $this->getOrderResetGoodsList($orderGoods,$CommodityArchiveGoods,$is_router_user);
        $orderGoodsMap = $orderGoodsGroup['orderGoodsGroup'];
        
        //获取bbc商品下单数据
        //获取下单最优商品
        $args = [
            'bid'               => $bid,
            'goods_list'        => $orderGoodsGroup['orderGoods'],
            'isBbcOrder'        => true,
            'is_router_user'    => $is_router_user,
            'orderType'         => $requestData['order_type'] ?? 0,
        ];
        $res = callRpcCommodityServer('getOrderRealGoodsList',$args);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        $bestGoods = $res['data']['bestGoodsList'];
        $userAuthGoodsList = $res['data']['userAuthGoodsList'];
        
        //组装下单获取微服务接口商品数据请求参数
        $authGoods = array_column($userAuthGoodsList,null,'skucode');
        
        //检查商品下单情况
        $res = $this->checkoutOrderCommodityStatus(['micServiceGoodsData'=>$bestGoods,'orderParam'=>$param]);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        //获取所有运费模板的最佳模板（区 -> 市 -> 省 -> 全国）反找
        $template_ids = array_column($bestGoods, 'freightTemplateID');
        $template_ids = array_filter(array_unique($template_ids));
        $templateInfo = FreightTemplateArea::instance()->getGoodsTemplateByIds($template_ids);
        $supplierGoodsGroup = $bestGoodsGroup = $supplierGoodsList = $authGoodsList = $userGoodsList = [];
        foreach ($bestGoods as $currentGoods ) 
        {
            $skucode        = $currentGoods['skuCode'];
            $supplierCode   = $currentGoods['thirdPartyPlatformCode'] ? $currentGoods['thirdPartyPlatformCode'] : $currentGoods['supplierCode'];
            //原始数据分组
            $supplierGoodsList[$supplierCode][$skucode] = $currentGoods;
            if( !isset($orderGoodsMap[$skucode]) ) {
                return Normal::returnCode(Normal::FAIL,"你所购买的商品【{$skucode}】暂无库存，请联系客服[1004]");
            }
            //组装分组
            $supplierGoodsList[$supplierCode][$skucode] = $currentGoods;
            //下单商品
            $userGoodsList[$supplierCode][$skucode] = $orderGoodsMap[$skucode];
            //授权商品分组
            $authGoodsList[$supplierCode][$skucode] = $authGoods[$skucode];
            //最优商品分组
            $bestGoodsGroup[$supplierCode][$skucode] = $currentGoods;
            
            //处理下单接口参数 判断是接口仓才进行
            $JsonBody = @json_decode($currentGoods['JsonBody'],true);
            $JsonBody = $JsonBody ? $JsonBody : [];
            //进行供应商商品分组
            $supplierGoodsGroup[$supplierCode] = [
                'supplierCode'              => $supplierCode,
                'warehouseAccount'          => $currentGoods['warehouseAccount'],
                'warehouseID'               => $currentGoods['warehouseID'],
                'supplierID'                => $currentGoods['supplierID'],
                'orderDockMode'             => $currentGoods['orderDockMode'],
                'orderDeclare'              => $currentGoods['orderDeclare'],
                'payDeclare'                => $currentGoods['payDeclare'],
                'apiBody'                   => $JsonBody,
                'thirdPartyPlatformCode'    => $currentGoods['thirdPartyPlatformCode'],
                'isCombineOrders'           => $currentGoods['isCombineOrders'],
                'authGoodsList'             => $authGoodsList[$supplierCode],
                'userGoodsList'             => $userGoodsList[$supplierCode],
                'goodsList'                 => $bestGoodsGroup[$supplierCode],
                'canModifyStock'            => $currentGoods['canModifyStock'],
                'FastDeliveryType'          => $currentGoods['FastDeliveryType'],
            ];
        }
        return Normal::returnCode(Normal::SUC,"获取数据成功",[
            'micServiceGoods'  => $supplierGoodsGroup,
            'templateList'     => $templateInfo['templateList'] ?? [],
            'noSaleArea'       => $templateInfo['noSaleArea'] ?? [],
        ]);
    }
    
    /**
     * 检查申报支付单之后，下单情况
     */
    public function checkoutOrderCommodityStatus( $param = [] ) 
    {
        $micServiceGoodsData    = $param['micServiceGoodsData'];
        $orderParam             = $param['orderParam'];
        $requestData            = $orderParam['requestData'];
        $binfo                  = $orderParam['binfo'];
        $commodityTypesMap      = array_column($micServiceGoodsData,null,'supplierCommodityType');
        
        //判断下游是否已申报支付单或者订单
        $isDelcare = (
            ( isset($requestData['isOrderDeclare']) && $requestData['isOrderDeclare'] == 1) ||
            ( isset($requestData['isPayDeclare']) && $requestData['isPayDeclare'] == 1)
            ) ? 1 : 0;
        
        $isShop = isset($requestData['isSplitOrder']) && $requestData['isSplitOrder'] == 1 ? true : false ;
        if( $isShop ) {
            return Normal::returnCode(Normal::SUC,"校验完成");
        }
        
        //下游已做支付单的渠道商户限制
        if( $isDelcare && $binfo['is_skip_declare'] != 1 ) {
            
            //判断商品类型
            if( count($commodityTypesMap) > 1 ) {
                if( isset($commodityTypesMap[GOODS_TYPE_YBMY]) && isset($commodityTypesMap[GOODS_TYPE_BS]) ) {
                    return Normal::returnCode(Normal::FAIL,"下游已申报支付单或订单渠道商，一般贸易和保税商品不支持合并下单");
                }
                
                if( isset($commodityTypesMap[GOODS_TYPE_YBMY]) && isset($commodityTypesMap[GOODS_TYPE_ZY]) ) {
                    return Normal::returnCode(Normal::FAIL,"下游已申报支付单或订单渠道商，一般贸易和直邮商品不支持合并下单");
                }
                
                if( isset($commodityTypesMap[GOODS_TYPE_BS]) && isset($commodityTypesMap[GOODS_TYPE_ZY]) ) {
                    return Normal::returnCode(Normal::FAIL,"下游已申报支付单或订单渠道商，保税和直邮商品不支持合并下单");
                }
            }
            
            //判断是否跨供应商,
            $commodityType = current($commodityTypesMap)['supplierCommodityType'];
            
            //如果是保税或者海外直邮的情况下(一般贸易也需要拆分订单)
            if( count($micServiceGoodsData) > 1 && in_array($commodityType,[GOODS_TYPE_BS,GOODS_TYPE_ZY,GOODS_TYPE_YBMY]) ) {
            
                //不能跨供应商下单
                $supplierGroupMap = array_column($micServiceGoodsData,null,'supplierCode');
                if( count($supplierGroupMap) > 1 ) {
                    return Normal::returnCode(Normal::FAIL,"不支持跨供应商多品购买，建议一单一品购买[100000]");
                }
                
                //如果是单个供应商,多品（保税或者海外直邮），只允许指定供应商或者自建仓供应商可以下订单
                $currentRow         = current($supplierGroupMap);
                //是否合并支付
                $isCombineOrders    = $currentRow['isCombineOrders'] ? true : false ;
                $supplierCode       = strtolower($currentRow['supplierCode']);
                if( $currentRow['orderDockMode'] == 0 && !$isCombineOrders ) {
                    return Normal::returnCode(Normal::FAIL,"当前供应商不支持合并多品购买，建议一单一品购买[100001]");
                }
            }
        }
        return Normal::returnCode(Normal::SUC,"校验完成");
    }
}